/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ssp.service;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import ssp.ResourceManager;
import ssp.SimulationManager;

/**
 * シミュレーション中のServiceEntryを記憶しておくクラス
 * @author yamazaki
 */
public class ServiceEntryPool implements ResourceManager {
    
    /**
     * シミュレーション中で唯一のクラスインスタンス
     */
    private static ServiceEntryPool INSTANCE = new ServiceEntryPool();
    
    /**
     * シミュレーション中のServiceEntryのリスト
     */
    private List<ServiceEntry> serviceEntryList;
    
    /**
     * コンストラクタ<br>
     * シングルトンのためprivateアクセス
     */
    private ServiceEntryPool() {
        init();
        SimulationManager.register(this);
    }

    @Override
    public final void init() {
        this.serviceEntryList = new ArrayList<>(1500);
    }

    /**
     * @return the INSTANCE
     */
    public static ServiceEntryPool getINSTANCE() {
        return INSTANCE;
    }
    
    /**
     * 指定のServiceEntryを管理に加える
     * @param entry 
     */
    public void add(ServiceEntry entry) {
        this.serviceEntryList.add(entry);
    }
    
    /**
     * @return the ServiceEntryList
     */
    public List<ServiceEntry> getServiceEntryList() {
        return this.serviceEntryList;
    }
    
    /**
     * シミュレーション中のServiceEntry数を返す
     * @return シミュレーション中のServiceEntry数
     */
    public int getServiceEntryNum() {
        return this.serviceEntryList.size();
    }
    
    /**
     * 指定のIDに対応するサービスエントリのリストを返す
     * @param ID ServiceEntryのリスト
     * @return 指定のIDに対応するサービスエントリのリスト
     */
    public List<ServiceEntry> getIDofServiceEntry(int ID) {
        List<ServiceEntry> newList = new ArrayList<>();
        for(ServiceEntry entry : this.serviceEntryList) {
            if(entry.getTypeID() == ID) {
                newList.add(entry);
            }
        }
        return newList;
    }
    
    /**
     * 指定のIDと品質指標のindexに対応する最大の品質値を返す
     * @param ID ServiceEntryのID
     * @param index 品質指標
     * @return 最大値
     */
    public int MaxQoSindex(int ID, int index) {
        LinkedList<ServiceEntry> newList = new LinkedList<>(getIDofServiceEntry(ID));
        Collections.sort(newList, new QoSindexDescending(index));
        return newList.getFirst().getQoSindex(index);
    }
    
    /**
     * 指定の品質指標の降順に並べ替えるためのComarator
     */
    private class QoSindexDescending implements Comparator<ServiceEntry>, Serializable {
        
        private static final long serialVersionUID = 6401867230403134834L;
        
        /**
         * 品質指標のindex
         */
        private int index;
        
        /**
         * コンストラクタ
         * @param index 品質指標のindex 
         */
        private QoSindexDescending(int index) {
            this.index = index;
        }

        @Override
        public int compare(ServiceEntry o1, ServiceEntry o2) {
            return o2.getQoSindex(index) - o1.getQoSindex(index);
        }
        
    }
    
}
